package com.jfinal.ext.generator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import com.jfinal.kit.StrKit;
import com.sun.mail.imap.protocol.ID;

/**
 * Web Pages 生成器, 针对BJUI Web框架
 */
public class WebPageGenerator {
    protected String editPageBeginPartTemplate = "<#include \"../common/_layout.html\" />\n" + "<@head title=\"%s\">\n"
            + "<style type=\"text/css\">\n" + "\t.cll {\n" + "\t\tbackground-color: #ddd;\n" + "\t}\n" + "</style>\n"
            + "</@head>\n" + "<@layout menu='/%s'>\n" + "<section class=\"content-header\">\n" + "\t<h1>\n"
            + "\t\t${pageTitleBread.department!pageTitleBread.default!}\n" + "\t</h1>\n" + "\t<ol class=\"breadcrumb\">\n"
            + "\t\t<li><a href=\"javascript:void(0);\" onclick=\"location.href='${ctx}${pageTitleBread.breadHomeMethod!}'\">首页</a></li>\n"
            + "\t\t<li><a href=\"javascript:void(0);\" onclick=\"location.href='${ctx}${pageTitleBread.url!}'\">${pageTitleBread.pageTitle!}</a></li>\n"
            + "\t\t<li class=\"active\">${pageTitleBread.nowBread!}</li>\n"
            + "\t</ol>\n"
            + "</section>\n" + "<section class=\"content\">\n" + "\t<div class=\"row\">\n"
            + "\t\t<div class=\"col-xs-12\">\n" + "\t\t\t<div class=\"box\">\n"
            + "\t\t\t\t<form action=\"${ctx}/%s/save\" method=\"post\" role=\"form\">\n"
            + "\t\t\t\t\t<legend>添加/修改信息</legend>\n"
            + "\t\t\t\t\t<input type=\"hidden\" name=\"%s\" id=\"%s\" value=\"%s\">\n";
    // "<#include
    // \"/common/template.html\"
    // />%n"
    // + "<div class=\"bjui-pageContent\">%n"
    // + "\t<form method=\"post\" action=\"%s/save\"
    // data-toggle=\"validate\">%n"
    // + "\t\t<input type=\"hidden\" name=\"id\" value=\"${%s.id}\">%n"
    // + "\t\t<table class=\"table table-condensed table-hover\">%n" +
    // "\t\t\t<tbody>%n";
    protected String trBeginTemplate = "\t\t\t\t<tr>%n";
    protected String tdBeginTemplate = "\t\t\t\t\t<td>%n";
    protected String tdColspan2BeginTemplate = "\t\t\t\t\t<td colspan=\"2\">%n";
    // form label
    protected String formLabelTemplate = "\t\t\t\t\t\t<label class=\"control-label x100\">%s：</label>%n";
    // form control
    protected String formControlTextTemplate = "\t\t\t\t\t<div class=\"form-group\">\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "\t\t\t\t\t\t<input type=\"text\" class=\"form-control\" id=\"%s\" name=\"%s\" placeholder=\"%s\" value=\"%s\">\n"
            + "\t\t\t\t\t</div>\n";// "\t\t\t\t\t\t<input
    // class=\"form-control\"
    // type=\"text\"
    // name=\"%s\"
    // value=\"${%s.%s}\" %s
    // size=\"30\"/>%n";
    // "<#include \"../common/_layout.html\" />%n"
    // + "<@layout actionUrl=\"%s/\">%n" + "\t<div class=\"bjui-pageHeader\">%n"
    // + "\t\t<form data-toggle=\"validate\" action=\"%s\" method=\"post\">%n"
    // + "\t\t\t<div class=\"bjui-searchBar\">%n" + "\t\t\t\t<div
    // class=\"btn-group\" role=\"group\">%n"
    // + "\t\t\t\t\t<a class=\"btn btn-blue\" href=\"%s/edit/0\"
    // data-toggle=\"navtab\" data-id=\"%s-add\" data-title=\"添加信息\" ><i
    // class=\"fa fa-plus\"></i> 添加</a>%n"
    // + "\t\t\t\t\t<a class=\"btn btn-green\" href=\"%s/edit/{#bjui-selected}\"
    // data-toggle=\"navtab\" data-id=\"%s-edit\" data-title=\"修改信息\" ><i
    // class=\"fa fa-edit\"></i> 编辑</a>%n"
    // + "\t\t\t\t\t<button type=\"button\" class=\"btn btn-red\"
    // onclick=\"doajax(this,true,'%s/delete/{#bjui-selected}',
    // '确定要删除选中项吗？')\"><i class=\"fa fa-remove\"></i> 删除</button>%n"
    // + "\t\t\t\t</div>%n"
    // + "\t\t\t\t<div class=\"alert alert-info search-inline\"><i class=\"fa
    // fa-info-circle\"></i> 单击选中行，支持批量删除</div>%n"
    // + "\t\t\t</div>%n" + "\t\t</form>%n" + "\t</div>%n" + "\t<div
    // class=\"bjui-pageContent\">%n"
    // + "\t\t<table class=\"table table-striped\"
    // data-selected-multi=\"ture\">%n" + "\t\t\t<thead>%n"
    // + "\t\t\t\t<tr>%n";
    protected String formControlTextNumberTemplate = "\t\t\t\t\t<div class=\"form-group\">\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "\t\t\t\t\t\t<input type=\"number\" class=\"form-control\" id=\"%s\" name=\"%s\" placeholder=\"%s\" value=\"%s\">\n"
            + "\t\t\t\t\t</div>\n";
    protected String formControlTextAreaTemplate = "\t\t\t\t\t<div class=\"form-group\">\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "                        <textarea id=\"%s\" name=\"%s\" class=\"form-control\" rows=\"5\">%s</textarea>\n"
            + "\t\t\t\t\t</div>\n";// "\t\t\t\t\t\t<textarea
    // name=\"%s\"
    // cols=\"87\"
    // rows=\"1\"
    // data-toggle=\"autoheight\"
    // %s>${%s.%s}</textarea>%n";
    protected String formControlRadioTemplate = "\t\t\t\t\t\t<input type=\"radio\" name=\"%s\" data-toggle=\"icheck\" value=\"true\" data-rule=\"checked\" data-label=\"是&nbsp;&nbsp;\" <#if true==%s.%s>checked</#if>>%n"
            + "\t\t\t\t\t\t<input type=\"radio\" name=\"%s\" data-toggle=\"icheck\" value=\"false\" data-label=\"否\" <#if false==%s.%s>checked</#if>>%n";
    protected String formControlDateTemplate = "\t\t\t\t\t<div class=\"form-group\">\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "\t\t\t\t\t\t<input type=\"date\" class=\"form-control\" id=\"%s\" name=\"%s\" value=\"%s\">\n"
            + "\t\t\t\t\t</div>\n";// "\t\t\t\t\t\t<input
    // type=\"text\"
    // name=\"%s\"
    // value=\"${%s.%s}\"
    // data-toggle=\"datepicker\"
    // %s size=\"30\">%n";
    protected String tdEndTemplate = "\t\t\t\t\t</td>%n";
    // + "\t\t</table>%n" + "\t</div>%n" + "</@layout>%n" + "<script
    // type=\"text/javascript\">%n"
    // + "\t// some script white here ...%n" + "</script>%n";
    protected String trEndTemplate = "\t\t\t\t</tr>%n";
    protected String editPageEndPartTemplate = "\t\t\t\t\t<button type=\"submit\" class=\"btn btn-primary\">保存</button><button type=\"button\" class=\"btn btn-cancle\" onclick=\"javascript :history.back(-1);\">返回</button>\n"
            + "\t\t\t\t</form>\n" + "\t\t\t</div>\n" + "\t\t</div>\n" + "\t</div>\n" + "</section>\n" + "</@layout>\n"
            + "<@scripts>\n" + "<script type=\"text/javascript\">\n" + "\t$(document).ready(function(){\n" + "\n"
            + "\t});\n" + "</script>\n" + "</@scripts>";// "\t\t\t</tbody>%n" +
    // "\t\t</table>%n" +
    // "\t</form>%n" +
    // "</div>%n"
    // + "<div class=\"bjui-pageFooter\">%n" + "\t<ul>%n"
    // + "\t\t<li><button type=\"button\" class=\"btn-close\"
    // data-icon=\"close\">关闭</button></li>%n"
    // + "\t\t<li><button type=\"submit\" class=\"btn btn-blue\"
    // data-icon=\"save\">提 交</button></li>%n"
    // + "\t</ul>%n" + "</div>%n" + "<script>%n" +
    // "\t$(document).ready(function() {%n" + "\t\t// 字典调用%n"
    // + "\t\t//ajaxSelected('#control-id', '/dict/somedict', '${somevar}')%n" +
    // "\t})%n" + "</script>%n";
    protected String webPageOutputDir;

    // index.html template
    protected String indexPageBeginPartTemplate = "<#include \"../common/_layout.html\"/>\n" + "<@head title=\"%s\">\n"
            + "<style type=\"text/css\">\n" + "    .cll {\n" + "        background-color: #ddd;\n" + "    }\n"
            + "</style>\n" + "</@head>\n" + "<@layout menu='/%s'>\n" + "<!-- Content Header (Page header) -->\n"
            + "<section class=\"content-header\">\n" + "    <h1>\n" + "        ${pageTitleBread.department!pageTitleBread.default!}\n" + "    </h1>\n"
            + "    <ol class=\"breadcrumb\">\n"
            + "        <li><a href=\"javascript:void(0);\" onclick=\"location.href='${ctx}${pageTitleBread.breadHomeMethod!}'\">首页</a></li>\n"
            + "        <li class=\"active\">${pageTitleBread.nowBread!}</li>\n"
            + "    </ol>\n"
            + "</section>\n" + "\n" + "<!-- Main content -->\n" + "<section class=\"content\">\n"
            + "    <div class=\"row\">\n" + "        <div class=\"col-xs-12\">\n" + "            <div class=\"box\">\n"
            + "                <form action=\"${ctx}/%s\" id=\"listForm\" method=\"post\" role=\"form\">\n"
            + "                    <div class=\"box-header\">\n"
            + "                        <h3 class=\"box-title\">%s</h3>\n"
            + "                        <div class=\"box-tools\">\n"
            + "                            <div class=\"input-group\" style=\"width: 300px;\">\n"
            + "                                <input type=\"text\" name=\"prjName\" id=\"prjName\" class=\"form-control input-sm pull-right\"\n"
            + "                                       placeholder=\"Search\">\n"
            + "                                <div class=\"input-group-btn\">\n"
            + "                                    <button class=\"btn btn-sm btn-default\"><i class=\"fa fa-search\"></i></button>\n"
            + "                                </div>\n" + "                            </div>\n"
            + "                        </div>\n" + "                    </div><!-- /.box-header -->\n"
            + "                    <div class=\"box-body table-responsive no-padding\">\n"
            + "                        <button type=\"button\" class=\"btn btn-default\" onclick=\"location.href='${ctx}/%s/edit'\">新增</button>\n"
            + "                        <button type=\"button\" id=\"deleteButton\" disabled=\"disabled\" class=\"btn btn-default\"\n"
            + "                                onclick=\"deleteAll('${ctx}/%s/delete')\">删除\n"
            + "                        </button>\n" + "                        <table class=\"table table-hover\">\n"
            + "                            <tr class=\"info\">\n";
    ;

    protected String indexPageListHeaderTemplate = "                                <th title=\"%s\">%s</th>\n";

    protected String indexPageMidPartTemplate = "                                <th>编辑</th>\n"
            + "                            </tr>\n" + "                            <#list page.getList() as item>\n"
            + "                                <tr>%n";

    protected String indexPageListContentTemplate = "                                    <td>%s</td>\n";

    protected String indexPageEndPartTemplate = "                                    <td>\n"
            + "                                        <button type=\"button\" class=\"btn btn-info\"\n"
            + "                                                onclick=\"location.href='/%s/edit?%s=${item.%s}'\">编辑\n"
            + "                                        </button>\n" + "                                    </td>\n"
            + "                                </tr>\n" + "                            </#list>\n"
            + "                        </table>\n" + "                        <#if (page.list?size>0)>\n"
            + "                        <#include \"../common/pager.html\">\n" + "                        </#if>\n"
            + "                    </div>\n" + "                </form>\n" + "            </div>\n" + "        </div>\n"
            + "    </div>\n" + "</section>\n" + "</@layout>\n" + "<@scripts>\n"
            + "<script type=\"text/javascript\" src=\"/adminlte/plugins/bootbox/bootbox.min.js\"></script>\n"
            + "<script type=\"text/javascript\" src=\"/js/list.js\"></script>\n" + "<script type=\"text/javascript\">\n"
            + "    $(document).ready(function () {\n" + "\n" + "    });\n" + "</script>\n" + "</@scripts>";


    protected String formControlTextTemplateValidator = "\t\t\t\t\t<div class=\"form-group\">\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "\t\t\t\t\t\t<input type=\"text\" class=\"form-control\" id=\"%s\" name=\"%s\" placeholder=\"%s\" value=\"%s\" <#if %s??>autofocus=\"autofocus\"  </#if>>\n"
            + "\t\t\t\t\t\t<small class=\"help-block\" <#if !%s??>style=\"display:none\" </#if>><#if %s??>${%s!}</#if></small>\n"
            + "\t\t\t\t\t</div>\n";// "\t\t\t\t\t\t<input
    // class=\"form-control\"
    // type=\"text\"
    // name=\"%s\"
    // value=\"${%s.%s}\" %s
    // size=\"30\"/>%n";
    // "<#include \"../common/_layout.html\" />%n"
    // + "<@layout actionUrl=\"%s/\">%n" + "\t<div class=\"bjui-pageHeader\">%n"
    // + "\t\t<form data-toggle=\"validate\" action=\"%s\" method=\"post\">%n"
    // + "\t\t\t<div class=\"bjui-searchBar\">%n" + "\t\t\t\t<div
    // class=\"btn-group\" role=\"group\">%n"
    // + "\t\t\t\t\t<a class=\"btn btn-blue\" href=\"%s/edit/0\"
    // data-toggle=\"navtab\" data-id=\"%s-add\" data-title=\"添加信息\" ><i
    // class=\"fa fa-plus\"></i> 添加</a>%n"
    // + "\t\t\t\t\t<a class=\"btn btn-green\" href=\"%s/edit/{#bjui-selected}\"
    // data-toggle=\"navtab\" data-id=\"%s-edit\" data-title=\"修改信息\" ><i
    // class=\"fa fa-edit\"></i> 编辑</a>%n"
    // + "\t\t\t\t\t<button type=\"button\" class=\"btn btn-red\"
    // onclick=\"doajax(this,true,'%s/delete/{#bjui-selected}',
    // '确定要删除选中项吗？')\"><i class=\"fa fa-remove\"></i> 删除</button>%n"
    // + "\t\t\t\t</div>%n"
    // + "\t\t\t\t<div class=\"alert alert-info search-inline\"><i class=\"fa
    // fa-info-circle\"></i> 单击选中行，支持批量删除</div>%n"
    // + "\t\t\t</div>%n" + "\t\t</form>%n" + "\t</div>%n" + "\t<div
    // class=\"bjui-pageContent\">%n"
    // + "\t\t<table class=\"table table-striped\"
    // data-selected-multi=\"ture\">%n" + "\t\t\t<thead>%n"
    // + "\t\t\t\t<tr>%n";
    protected String formControlTextNumberTemplateValidator = "\t\t\t\t\t<div class=\"form-group\">\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "\t\t\t\t\t\t<input type=\"number\" class=\"form-control\" id=\"%s\" name=\"%s\" placeholder=\"%s\" value=\"%s\"<#if %s??>autofocus=\"autofocus\"  </#if>>\n"
            + "\t\t\t\t\t\t<small class=\"help-block\" <#if !%s??>style=\"display:none\" </#if>><#if %s??>${%s!}</#if></small>\n"
            + "\t\t\t\t\t</div>\n";
    protected String formControlTextAreaTemplateValidator = "\t\t\t\t\t<div class=\"form-group\" >\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "                        <textarea id=\"%s\" name=\"%s\" class=\"form-control\" rows=\"5\" <#if %s??>autofocus=\"autofocus\"  </#if>>%s</textarea>\n"
            + "\t\t\t\t\t\t<small class=\"help-block\" <#if !%s??>style=\"display:none\" </#if>><#if %s??>${%s!}</#if></small>\n"
            + "\t\t\t\t\t</div>\n";// "\t\t\t\t\t\t<textarea
    // name=\"%s\"
    // cols=\"87\"
    // rows=\"1\"
    // data-toggle=\"autoheight\"
    // %s>${%s.%s}</textarea>%n";
    protected String formControlRadioTemplateValidator = "\t\t\t\t\t\t<input type=\"radio\" name=\"%s\" data-toggle=\"icheck\" value=\"true\" data-rule=\"checked\" data-label=\"是&nbsp;&nbsp;\" <#if true==%s.%s>checked</#if>>%n"
            + "\t\t\t\t\t\t<input type=\"radio\" name=\"%s\" data-toggle=\"icheck\" value=\"false\" data-label=\"否\" <#if false==%s.%s>checked</#if>>%n";
    protected String formControlDateTemplateValidator = "\t\t\t\t\t<div class=\"form-group\">\n"
            + "\t\t\t\t\t\t<label for=\"%s\">%s</label>\n"
            + "\t\t\t\t\t\t<input type=\"date\" class=\"form-control\" id=\"%s\" name=\"%s\" value=\"%s\" <#if %s??>autofocus=\"autofocus\"  </#if>>\n"
            + "\t\t\t\t\t\t<small class=\"help-block\" <#if !%s??>style=\"display:none\" </#if>><#if %s??>${%s!}</#if></small>\n"
            + "\t\t\t\t\t</div>\n";// "\t\t\t\t\t\t<input
    // type=\"text\"
    // name=\"%s\"
    // value=\"${%s.%s}\"
    // data-toggle=\"datepicker\"
    // %s size=\"30\">%n";


    public WebPageGenerator(String webPageOutputDir) {
        if (StrKit.isBlank(webPageOutputDir))
            throw new IllegalArgumentException("webPageOutputDir can not be blank.");

        this.webPageOutputDir = webPageOutputDir;
    }

    public void generate(List<TableMeta> tableMetas) {
        System.out.println("Generate Web Pages ...");
        for (TableMeta tableMeta : tableMetas)
            genIndexPageContent(tableMeta);
        wirtToFile(tableMetas, "index.html");

        for (TableMeta tableMeta : tableMetas)
            genEditPageContent(tableMeta);
        wirtToFile(tableMetas, "edit.html");
    }

    protected void genIndexPageContent(TableMeta tableMeta) {
        StringBuilder ret = new StringBuilder();
        genIndexPageBeginPart(tableMeta, ret);
        genIndexPageListHeader(tableMeta, ret);
        genIndexPageMidPart(ret);
        genIndexPageListContent(tableMeta, ret);
        genIndexPageEndPart(tableMeta, ret);
        tableMeta.modelContent = ret.toString();
    }

    protected void genEditPageContent(TableMeta tableMeta) {
        StringBuilder ret = new StringBuilder();
        genEditPageFormBegin(tableMeta, ret);
        genEditPageFormContent(tableMeta, ret);
        geneditPageFormEnd(ret);
        tableMeta.modelContent = ret.toString();
    }

    protected void genIndexPageBeginPart(TableMeta tableMeta, StringBuilder ret) {
        String s = tableMeta.modelName.toLowerCase().replaceAll("_", "");
        ret.append(String.format(indexPageBeginPartTemplate, tableMeta.remarks, s, s, tableMeta.remarks, s, s));
    }

    private boolean noFilter(ColumnMeta columnMeta) {
        if (columnMeta.isPrimaryKey.equalsIgnoreCase("PRI") || columnMeta.name.equals("Explains")
                || columnMeta.name.equals("Remarks") || columnMeta.name.equals("Logo_Photo_URL")
                || columnMeta.name.equals("User_Code") || columnMeta.name.equals("User_Name")
                || columnMeta.name.equals("Create_Time") || columnMeta.name.equals("Edit_Time")
                || columnMeta.name.equals("userCode") || columnMeta.name.equals("createTime")
                || columnMeta.name.equals("editTime") || columnMeta.equals("createDate")
                || columnMeta.equals("modifyDate"))
            return false;
        return true;
    }

    protected void genIndexPageListHeader(TableMeta tableMeta, StringBuilder ret) {
        for (ColumnMeta columnMeta : tableMeta.columnMetas)
            if (noFilter(columnMeta)) {
                ret.append(String.format(indexPageListHeaderTemplate, columnMeta.remarks, columnMeta.remarks));
            } else {
                ret.append(String.format(indexPageListHeaderTemplate, columnMeta.remarks,
                        String.format("<input type=\"checkbox\" id=\"allCheck\">")));
            }
    }

    protected void genIndexPageMidPart(StringBuilder ret) {
        ret.append(String.format(indexPageMidPartTemplate));
    }

    protected void genIndexPageListContent(TableMeta tableMeta, StringBuilder ret) {
        for (ColumnMeta columnMeta : tableMeta.columnMetas)
            if (noFilter(columnMeta)) {
                ret.append(String.format(indexPageListContentTemplate, String.format("${item.%s!}",
                        columnMeta.type.contains("BIT") ? columnMeta.name : columnMeta.name)));
            } else {
                ret.append(String.format(indexPageListContentTemplate,
                        String.format("<input type=\"checkbox\" name=\"ids\" value=\"${item.%s!}\">",
                                columnMeta.type.contains("BIT") ? columnMeta.name : columnMeta.name)));
            }
    }

    protected void genIndexPageEndPart(TableMeta tableMeta, StringBuilder ret) {
        String s = tableMeta.modelName.toLowerCase().replaceAll("_", "");
        ret.append(String.format(indexPageEndPartTemplate, s, tableMeta.primaryKey, tableMeta.primaryKey));
    }

    protected void genEditPageFormBegin(TableMeta tableMeta, StringBuilder ret) {
        String s = tableMeta.name.toLowerCase().replaceAll("_", "");
        String ID_NAME = StrKit.firstCharToLowerCase(tableMeta.modelName) + "." + tableMeta.primaryKey;
        ret.append(String.format(editPageBeginPartTemplate, tableMeta.remarks + "编辑", s, s, ID_NAME,
                ID_NAME,
                String.format("${%s.%s!}", StrKit.firstCharToLowerCase(tableMeta.modelName), tableMeta.primaryKey)));
    }

    protected void genEditPageFormContent(TableMeta tableMeta, StringBuilder ret) {
        int count = 0;
        Boolean first = true;
        for (ColumnMeta columnMeta : tableMeta.columnMetas) {
            if (!noFilter(columnMeta))
                continue;

            boolean isTextArea = false;
            boolean isTextNumer = false;
            if (columnMeta.type.contains("(") && columnMeta.type.contains(")")
                    && com.jfinal.ext.kit.StrKit.hasDigit(columnMeta.type))
                isTextArea = Integer.parseInt(columnMeta.type.substring(columnMeta.type.indexOf('(') + 1,
                        columnMeta.type.indexOf(')'))) >= 500;
            if (columnMeta.type.contains("DECIMAL") || columnMeta.type.contains("TINYINT")
                    || columnMeta.type.contains("DOUBLE") || columnMeta.type.contains("INTEGER")
                    || columnMeta.type.contains("FLOAT") || columnMeta.type.contains("INT"))
                isTextNumer = true;
            // BIT DATETIME(19)
            String MsgName = columnMeta.name + "Msg";
            String idName = StrKit.firstCharToLowerCase(tableMeta.modelName) + "." + columnMeta.name;
            if (columnMeta.type.contains("DATE") || columnMeta.type.contains("TIME")
                    || columnMeta.type.contains("TIMESTEMP")) {
                if (columnMeta.isNullable.equals("NO"))
                    ret.append(String.format(formControlDateTemplateValidator, idName, columnMeta.remarks, idName,
                            idName,
                            String.format("<#if %s.%s??>${%s.%s?date}</#if>",
                                    StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name,
                                    StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name), MsgName, MsgName, MsgName, MsgName));

                else
                    ret.append(String.format(formControlDateTemplate, idName, columnMeta.remarks, idName, idName,
                            String.format("<#if %s.%s??>${%s.%s?date}</#if>",
                                    StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name,
                                    StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name)));

            } // else if (columnMeta.type.contains("BIT"))
            // ret.append(String.format(formControlRadioTemplate,
            // columnMeta.name,
            // StrKit.firstCharToLowerCase(tableMeta.modelName),
            // columnMeta.name, columnMeta.name,
            // StrKit.firstCharToLowerCase(tableMeta.modelName),
            // columnMeta.name));
            else if (isTextArea) {
                if (columnMeta.isNullable.equals("NO"))
                    ret.append(String.format(formControlTextAreaTemplateValidator, idName, columnMeta.remarks,
                            idName, idName, MsgName,
                            String.format("${%s.%s!}", StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name), MsgName, MsgName, MsgName));

                else
                    ret.append(String.format(formControlTextAreaTemplate, idName, columnMeta.remarks,
                            idName, idName,
                            String.format("${%s.%s!}", StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name)));

            } else if (isTextNumer) {
                if (columnMeta.isNullable.equals("NO"))
                    ret.append(String.format(formControlTextNumberTemplateValidator, idName, columnMeta.remarks, idName, idName, columnMeta.remarks,
                            String.format("${%s.%s!}", StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name), MsgName, MsgName, MsgName, MsgName));
                else
                    ret.append(String.format(formControlTextNumberTemplate, idName, columnMeta.remarks, idName, idName, columnMeta.remarks,
                            String.format("${%s.%s!}", StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name)));
            } else {
                if (columnMeta.isNullable.equals("NO"))
                    ret.append(String.format(formControlTextTemplateValidator, idName, columnMeta.remarks,
                            idName, idName, columnMeta.remarks,
                            String.format("${%s.%s!}", StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name), MsgName, MsgName, MsgName, MsgName));

                else
                    ret.append(String.format(formControlTextTemplate, idName, columnMeta.remarks,
                            idName, idName, columnMeta.remarks,
                            String.format("${%s.%s!}", StrKit.firstCharToLowerCase(tableMeta.modelName), columnMeta.name)));
            }

            // ret.append(String.format(tdEndTemplate));
            //
            // if (count > 0 && count % 2 == 1 || isTextArea) {
            // ret.append(String.format(trEndTemplate));
            // }
            // if (isTextArea)
            // count = 0;
            // else
            // count++;
        }
        // if (count % 2 == 1) {
        // ret.append(String.format(trEndTemplate));
        // }
    }

    protected void geneditPageFormEnd(StringBuilder ret) {
        ret.append(String.format(editPageEndPartTemplate));
    }

    protected void wirtToFile(List<TableMeta> tableMetas, String fileName) {
        try {
            for (TableMeta tableMeta : tableMetas)
                wirtToFile(tableMeta, fileName);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 若 webPage 文件存在，则不生成，以免覆盖用户手写的代码
     */
    protected void wirtToFile(TableMeta tableMeta, String fileName) throws IOException {
        File dir = new File(webPageOutputDir + File.separator + tableMeta.modelName.toLowerCase().replaceAll("_", ""));
        if (!dir.exists())
            dir.mkdirs();

        String target = webPageOutputDir + File.separator + tableMeta.modelName.toLowerCase().replaceAll("_", "")
                + File.separator + fileName;

        File file = new File(target);
        if (file.exists()) {
            return; // 若 page 存在，不覆盖
        }

        FileWriter fw = new FileWriter(file);
        try {
            fw.write(tableMeta.modelContent);
        } finally {
            fw.close();
        }
    }
}
